#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <stdbool.h>
#include <errno.h>
#include "config.h"
#include "log.h"

// 配置项节点结构体
typedef struct config_node {
    char *key;
    enum config_type type;
    union {
        int int_value;
        float float_value;
        char *string_value;
        bool bool_value;
    } value;
    struct config_node *next;
} config_node_t;

// 全局变量
static bool g_is_initialized = false;
static config_node_t *g_config_list = NULL;
static char g_config_file[256] = {0};
static pthread_mutex_t g_config_mutex = PTHREAD_MUTEX_INITIALIZER;

// 查找配置项
static config_node_t *find_config_node(const char *key)
{
    config_node_t *current = g_config_list;
    while (current != NULL) {
        if (strcmp(current->key, key) == 0) {
            return current;
        }
        current = current->next;
    }
    return NULL;
}

// 创建新的配置项
static config_node_t *create_config_node(const char *key)
{
    config_node_t *node = (config_node_t *)malloc(sizeof(config_node_t));
    if (!node) {
        LOG_ERROR("内存分配失败: %s", strerror(errno));
        return NULL;
    }
    
    node->key = strdup(key);
    if (!node->key) {
        LOG_ERROR("内存分配失败: %s", strerror(errno));
        free(node);
        return NULL;
    }
    
    node->next = NULL;
    return node;
}

// 释放配置项节点
static void free_config_node(config_node_t *node)
{
    if (!node) {
        return;
    }
    
    free(node->key);
    
    if (node->type == CONFIG_TYPE_STRING) {
        free(node->value.string_value);
    }
    
    free(node);
}

int config_init(void)
{
    pthread_mutex_lock(&g_config_mutex);
    
    if (g_is_initialized) {
        pthread_mutex_unlock(&g_config_mutex);
        return 0;
    }
    
    // 初始化默认配置文件路径
    strncpy(g_config_file, "/tmp/drone_demo.conf", sizeof(g_config_file) - 1);
    
    // 加载默认配置文件
    config_load(g_config_file);
    
    g_is_initialized = true;
    pthread_mutex_unlock(&g_config_mutex);
    
    LOG_INFO("配置模块初始化成功");
    return 0;
}

void config_cleanup(void)
{
    pthread_mutex_lock(&g_config_mutex);
    
    if (!g_is_initialized) {
        pthread_mutex_unlock(&g_config_mutex);
        return;
    }
    
    // 清理所有配置项
    config_node_t *current = g_config_list;
    config_node_t *next = NULL;
    
    while (current != NULL) {
        next = current->next;
        free_config_node(current);
        current = next;
    }
    
    g_config_list = NULL;
    g_config_file[0] = '\0';
    g_is_initialized = false;
    
    pthread_mutex_unlock(&g_config_mutex);
    
    LOG_INFO("配置模块清理完成");
}

int config_load(const char *config_file)
{
    if (!config_file) {
        LOG_ERROR("配置文件路径为空");
        return -1;
    }
    
    pthread_mutex_lock(&g_config_mutex);
    
    // 保存配置文件路径
    strncpy(g_config_file, config_file, sizeof(g_config_file) - 1);
    
    // 打开配置文件
    FILE *file = fopen(config_file, "r");
    if (!file) {
        LOG_WARN("无法打开配置文件: %s, 使用默认配置", config_file);
        pthread_mutex_unlock(&g_config_mutex);
        return 0; // 文件不存在不是错误
    }
    
    // 逐行读取配置
    char line[512];
    char key[256];
    char value[256];
    
    while (fgets(line, sizeof(line), file) != NULL) {
        // 跳过注释和空行
        if (line[0] == '#' || line[0] == '\n' || line[0] == '\r') {
            continue;
        }
        
        // 解析key=value格式
        if (sscanf(line, "%[^=]=%s", key, value) == 2) {
            // 根据值的格式判断类型并设置
            char *endptr;
            
            // 尝试作为整数解析
            long int_value = strtol(value, &endptr, 10);
            if (*endptr == '\0') {
                config_set_int(key, (int)int_value);
                continue;
            }
            
            // 尝试作为浮点数解析
            float float_value = strtof(value, &endptr);
            if (*endptr == '\0') {
                config_set_float(key, float_value);
                continue;
            }
            
            // 尝试作为布尔值解析
            if (strcmp(value, "true") == 0 || strcmp(value, "True") == 0 || strcmp(value, "1") == 0) {
                config_set_bool(key, true);
                continue;
            }
            if (strcmp(value, "false") == 0 || strcmp(value, "False") == 0 || strcmp(value, "0") == 0) {
                config_set_bool(key, false);
                continue;
            }
            
            // 否则作为字符串处理
            config_set_string(key, value);
        }
    }
    
    fclose(file);
    pthread_mutex_unlock(&g_config_mutex);
    
    LOG_INFO("配置文件加载成功: %s", config_file);
    return 0;
}

int config_save(const char *config_file)
{
    const char *file_path = config_file ? config_file : g_config_file;
    
    if (!file_path || file_path[0] == '\0') {
        LOG_ERROR("配置文件路径为空");
        return -1;
    }
    
    pthread_mutex_lock(&g_config_mutex);
    
    // 打开配置文件进行写入
    FILE *file = fopen(file_path, "w");
    if (!file) {
        LOG_ERROR("无法打开配置文件: %s, 错误: %s", file_path, strerror(errno));
        pthread_mutex_unlock(&g_config_mutex);
        return -1;
    }
    
    // 写入所有配置项
    config_node_t *current = g_config_list;
    while (current != NULL) {
        switch (current->type) {
            case CONFIG_TYPE_INT:
                fprintf(file, "%s=%d\n", current->key, current->value.int_value);
                break;
            case CONFIG_TYPE_FLOAT:
                fprintf(file, "%s=%f\n", current->key, current->value.float_value);
                break;
            case CONFIG_TYPE_STRING:
                fprintf(file, "%s=%s\n", current->key, current->value.string_value);
                break;
            case CONFIG_TYPE_BOOL:
                fprintf(file, "%s=%s\n", current->key, current->value.bool_value ? "true" : "false");
                break;
        }
        current = current->next;
    }
    
    fclose(file);
    pthread_mutex_unlock(&g_config_mutex);
    
    LOG_INFO("配置文件保存成功: %s", file_path);
    return 0;
}

int config_get_int(const char *key, int default_value)
{
    pthread_mutex_lock(&g_config_mutex);
    
    config_node_t *node = find_config_node(key);
    int value = default_value;
    
    if (node && node->type == CONFIG_TYPE_INT) {
        value = node->value.int_value;
    }
    
    pthread_mutex_unlock(&g_config_mutex);
    return value;
}

int config_set_int(const char *key, int value)
{
    pthread_mutex_lock(&g_config_mutex);
    
    config_node_t *node = find_config_node(key);
    
    if (!node) {
        node = create_config_node(key);
        if (!node) {
            pthread_mutex_unlock(&g_config_mutex);
            return -1;
        }
        
        // 插入到链表头部
        node->next = g_config_list;
        g_config_list = node;
    } else {
        // 如果是字符串类型，需要释放旧字符串
        if (node->type == CONFIG_TYPE_STRING) {
            free(node->value.string_value);
        }
    }
    
    node->type = CONFIG_TYPE_INT;
    node->value.int_value = value;
    
    pthread_mutex_unlock(&g_config_mutex);
    return 0;
}

float config_get_float(const char *key, float default_value)
{
    pthread_mutex_lock(&g_config_mutex);
    
    config_node_t *node = find_config_node(key);
    float value = default_value;
    
    if (node && node->type == CONFIG_TYPE_FLOAT) {
        value = node->value.float_value;
    }
    
    pthread_mutex_unlock(&g_config_mutex);
    return value;
}

int config_set_float(const char *key, float value)
{
    pthread_mutex_lock(&g_config_mutex);
    
    config_node_t *node = find_config_node(key);
    
    if (!node) {
        node = create_config_node(key);
        if (!node) {
            pthread_mutex_unlock(&g_config_mutex);
            return -1;
        }
        
        // 插入到链表头部
        node->next = g_config_list;
        g_config_list = node;
    } else {
        // 如果是字符串类型，需要释放旧字符串
        if (node->type == CONFIG_TYPE_STRING) {
            free(node->value.string_value);
        }
    }
    
    node->type = CONFIG_TYPE_FLOAT;
    node->value.float_value = value;
    
    pthread_mutex_unlock(&g_config_mutex);
    return 0;
}

int config_get_string(const char *key, const char *default_value, char *buffer, int buffer_size)
{
    if (!buffer || buffer_size <= 0) {
        return -1;
    }
    
    pthread_mutex_lock(&g_config_mutex);
    
    config_node_t *node = find_config_node(key);
    
    if (node && node->type == CONFIG_TYPE_STRING) {
        strncpy(buffer, node->value.string_value, buffer_size - 1);
        buffer[buffer_size - 1] = '\0';
    } else if (default_value) {
        strncpy(buffer, default_value, buffer_size - 1);
        buffer[buffer_size - 1] = '\0';
    } else {
        buffer[0] = '\0';
    }
    
    pthread_mutex_unlock(&g_config_mutex);
    return 0;
}

int config_set_string(const char *key, const char *value)
{
    if (!value) {
        return -1;
    }
    
    pthread_mutex_lock(&g_config_mutex);
    
    config_node_t *node = find_config_node(key);
    
    if (!node) {
        node = create_config_node(key);
        if (!node) {
            pthread_mutex_unlock(&g_config_mutex);
            return -1;
        }
        
        // 插入到链表头部
        node->next = g_config_list;
        g_config_list = node;
    } else {
        // 如果是字符串类型，需要释放旧字符串
        if (node->type == CONFIG_TYPE_STRING) {
            free(node->value.string_value);
        }
    }
    
    node->type = CONFIG_TYPE_STRING;
    node->value.string_value = strdup(value);
    if (!node->value.string_value) {
        LOG_ERROR("内存分配失败: %s", strerror(errno));
        free_config_node(node);
        pthread_mutex_unlock(&g_config_mutex);
        return -1;
    }
    
    pthread_mutex_unlock(&g_config_mutex);
    return 0;
}

bool config_get_bool(const char *key, bool default_value)
{
    pthread_mutex_lock(&g_config_mutex);
    
    config_node_t *node = find_config_node(key);
    bool value = default_value;
    
    if (node && node->type == CONFIG_TYPE_BOOL) {
        value = node->value.bool_value;
    }
    
    pthread_mutex_unlock(&g_config_mutex);
    return value;
}

int config_set_bool(const char *key, bool value)
{
    pthread_mutex_lock(&g_config_mutex);
    
    config_node_t *node = find_config_node(key);
    
    if (!node) {
        node = create_config_node(key);
        if (!node) {
            pthread_mutex_unlock(&g_config_mutex);
            return -1;
        }
        
        // 插入到链表头部
        node->next = g_config_list;
        g_config_list = node;
    } else {
        // 如果是字符串类型，需要释放旧字符串
        if (node->type == CONFIG_TYPE_STRING) {
            free(node->value.string_value);
        }
    }
    
    node->type = CONFIG_TYPE_BOOL;
    node->value.bool_value = value;
    
    pthread_mutex_unlock(&g_config_mutex);
    return 0;
}

int config_remove(const char *key)
{
    pthread_mutex_lock(&g_config_mutex);
    
    config_node_t *prev = NULL;
    config_node_t *current = g_config_list;
    
    while (current != NULL) {
        if (strcmp(current->key, key) == 0) {
            if (prev) {
                prev->next = current->next;
            } else {
                g_config_list = current->next;
            }
            
            free_config_node(current);
            pthread_mutex_unlock(&g_config_mutex);
            return 0;
        }
        
        prev = current;
        current = current->next;
    }
    
    pthread_mutex_unlock(&g_config_mutex);
    return -1; // 键不存在
}

bool config_has_key(const char *key)
{
    pthread_mutex_lock(&g_config_mutex);
    
    bool has_key = (find_config_node(key) != NULL);
    
    pthread_mutex_unlock(&g_config_mutex);
    return has_key;
}